package com.yufei.infoExtractor.parallel.thread;

import java.io.IOException;




import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

import junit.framework.Assert;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.yufei.infoExtractor.cache.CacheFactory;
import com.yufei.infoExtractor.cache.InfoExtractorCache;
import com.yufei.infoExtractor.extractor.PropertyExtractor;
import com.yufei.infoExtractor.extractor.propertyExtractor.PropertyExtractorFactory;
import com.yufei.infoExtractor.pfw.InfoExtractorDao;
import com.yufei.infoExtractor.pfw.entity.PropertyMatch;
import com.yufei.infoExtractor.pfw.entity.Relatedlink;
import com.yufei.infoExtractor.pfw.entity.Seedsite;
import com.yufei.infoExtractor.util.AppUtil;
import com.yufei.infoExtractor.util.CommonUtil;
import com.yufei.infoExtractor.util.EncryptUtil;

/**
 * created by @author jasstion at 2012-10-31 用于采集Urls的进程
 */
public class UrlFetchThread implements Runnable {
	public static final Log mLog = LogFactory.getLog(UrlFetchThread.class);
    private Map context=null;
	private List<String> readyUrls = null;
	private CountDownLatch countDownLatch = null;



	public List<String> getReadyUrls() {
		return readyUrls;
	}




	public UrlFetchThread(ThreadLocal<Map> threadLocalcontext, List<String> urlList,
			CountDownLatch countDownLatch) {
		// TODO Auto-generated constructor stub
		super();
		this.context=threadLocalcontext.get();
		this.readyUrls = urlList;
		this.countDownLatch = countDownLatch;
	}


	public void setReadyUrls(List<String> readyUrls) {
		this.readyUrls = readyUrls;
	}

	public CountDownLatch getCountDownLatch() {
		return countDownLatch;
	}

	public void setCountDownLatch(CountDownLatch countDownLatch) {
		this.countDownLatch = countDownLatch;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		fetchUrlList(this.context);

		countDownLatch.countDown();
		mLog.info("线程执行完毕");

	}

	private void fetchUrlList(Map context) {
		String currentHtmlContent = null;
		Relatedlink currentLink = null;
		Class entityClass = (Class) context.get("entityClass");
		String taskName = ((Seedsite) (context.get("seed"))).getTaskName();

		for (String url : readyUrls) {

			String urlMd5 = EncryptUtil.md5(url);

			try {
				currentLink = (Relatedlink) entityClass.newInstance();
				// Element
				// element=AppUtil.getCacheByCacheName(AppUtil.defaultUrlCache).get(urlMd5);
				InfoExtractorCache<String, String> urlCache = (InfoExtractorCache<String, String>) context
						.get("urlCache");
				currentHtmlContent = urlCache.get(urlMd5);
				if (currentHtmlContent == null) {
					currentHtmlContent = CommonUtil
							.getHtmlContent(context, url);

				}

				mLog.debug("获取连接内容：" + url);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				mLog.info("请求链接:" + url + "出错!");
				continue;
			}
			
          if(CommonUtil.isEmptyOrNull(currentHtmlContent)){
        	  continue;
          }
			// 对于有些需要重定向的网页处理
			String redirectUrl = (String) context.get("redirectUrl");
			if (redirectUrl == null) {
				redirectUrl = url;
			}

			currentLink.setLink(redirectUrl);

			// 目前无论采取何种方式抓取数据深度都设置为零
			currentLink.setDepth(0);
			// 设置url指纹用于去重判断
			currentLink.setHashCode(urlMd5);
			context.put("currentLink", currentLink);
			context.put("currentHtmlContent", currentHtmlContent);
			boolean isSuccess = setPropertiesOnLink(context);
			if (!isSuccess) {
				// 针对此链接处理失败，原因可能是此链接不是内容链接将此链接加入到当前指纹集合中避免下次重复处理
				mLog.debug("链接：" + url + "很可能为非内容链接，直接忽略！");
				continue;
			}

			InfoExtractorDao infoExtractorDao = (InfoExtractorDao) AppUtil
					.getBeanFromBeanContainer(InfoExtractorDao.class);
			infoExtractorDao.saveEntity(currentLink);

		}
	}

	/**
	 * @param context
	 * @return 表示针对此链接的处理是否成功用于判断后续是否保存
	 */
	public boolean setPropertiesOnLink(Map context) {
		Relatedlink link = (Relatedlink) context.get("currentLink");
		List<PropertyMatch> propertyMatches = (List<PropertyMatch>) context
				.get("propertyMatches");
		List<Field> fileds = CommonUtil.getAllDeclareFields(link.getClass());

		String htmlContent = (String) context.get("currentHtmlContent");
		


		/*
		 * if (mLog.isDebugEnabled()) { mLog.debug("此次entity解析的主题页面内容为：" +
		 * "\n\n\n" + htmlContent); }
		 */
		// 设置链接发现时间
		link.setFindTime(new Date());

		String fieldName = null;
		String value = null;
		PropertyMatch propertyMatch = null;
		String fieldRegex = null;
		for (Field field : fileds) {
			// collection
			propertyMatch = CommonUtil.getPropertyMatchFromListByPropertyName(
					field.getName(), propertyMatches);

			if (propertyMatch == null) {
				continue;
			}
			context.put("currentPropertyMatch", propertyMatch);
			PropertyExtractor propertyExtractor = PropertyExtractorFactory
					.getPropertyExtractor(propertyMatch);
			propertyExtractor.extract(context);

		}

		context.put("currentLink", link);
		return true;
	}
}
